﻿using Newtonsoft.Json;
using StackExchange.Redis;

namespace Msung.Core.Caching
{
    /// <summary>
    /// Redis缓存接口
    /// </summary>
    public interface IRedisOperationRepository
    {
        bool HashRemove(string redisKey, string redisfiedId);
        bool HashExist(string redisKey, string redisfiedId);
        bool HashSet(string redisKey, string redisfiedId,string  value);
        string HashGet(string redisKey, string redisfiedId);
        string? Get(string key, int server = 0, int db = -1);

        bool KeyRename(string key, string rkey);
        /// <summary>
        /// 获取头部第一个数据
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        string ListLeftPop(string redisKey);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sourceKey"></param>
        /// <param name="destination"></param>
        /// <returns></returns>
        string ListRightPopLeftPush(string sourceKey, string destination);
        /// <summary>
        ///  list 某个值 后面新增一条数据
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <param name="redisValue1"></param>
        /// <returns></returns>
        long ListInsertAfter(string redisKey, string redisValue, string redisValue1);
        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        bool Exist(string key);
        /// <summary>
        /// PipeLine 批量插入key wafer 专用
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="cacheTime"></param>
        /// <returns></returns>
        Task BatchSetAsync<T>(string key, List<T> value, TimeSpan? cacheTime = null);
        /// <summary>
        /// 模糊查询  wafer专用
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        Task<List<TEntity>> GetLikeEntityAsync<TEntity>(string key);
        /// <summary>
        /// 设置key过期时间
        /// </summary>
        /// <param name="key"></param>
        /// <param name="expiry"></param>
        /// <returns></returns>
        Task<bool> KeyExpireAsync(RedisKey key, TimeSpan? expiry);
        /// <summary>
        /// 设置key过期时间
        /// </summary>
        /// <param name="key"></param>
        /// <param name="expiry"></param>
        /// <returns></returns>
        bool KeyExpire(RedisKey key, TimeSpan? expiry);

        Task<long> IncrAsync(string key,int value=1);

         long Incr(string key, int value = 1);
        //获取 Reids 缓存值
        Task<string> GetAsync(string key);
        //获取 Reids 缓存值
         string  Get(string key);

        //获取 Reids 缓存值
        Task<TimeSpan?> KeyTimeAsync(string key);
        TimeSpan? KeyTime(string key);

        //获取值，并序列化
        Task<TEntity> GetAsync<TEntity>(string key);
        TEntity Get<TEntity>(string key);
       

        //保存
        Task SetAsync(string key, object value, TimeSpan? cacheTime = null);

        void  Set(string key, object value, TimeSpan? cacheTime = null);


        //判断是否存在
        Task<bool> ExistAsync(string key);

        //移除某一个缓存值
        Task RemoveAsync(string key);

        //移除某一个缓存值
        void Remove(string key);
        //全部清除
        Task Clear();

        /// <summary>
        /// 根据key获取RedisValue
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        Task<RedisValue[]> ListRangeAsync(string redisKey);

        
        /// <summary>
        /// 在列表头部插入值。如果键不存在，先创建再插入值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        Task<long> ListLeftPushAsync(string redisKey, string redisValue);
        /// <summary>
        /// 在列表头部插入值。如果键不存在，先创建再插入值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        long ListLeftPush(string redisKey, string redisValue);
        long ListLeftPush(string redisKey, object redisValue);

        Task<long> ListLeftPushAsync(string redisKey, object redisValue);
        Task ListLeftPushAsync<T>(string redisKey, List<T> redisValue);

        /// <summary>
        /// 在列表头部插入值。如果键不存在，先创建再插入值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        void ListLeftPush<T>(string redisKey, List<T> redisValue);
        /// <summary>
        /// 获取list 第一个数据
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns></returns>
        public string ListRangeFirst(string redisKey);
        /// <summary>
        /// 获取最后数据
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns></returns>
        public string ListRangeLast(string redisKey);
        /// <summary>
        /// 获取最后数据
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns></returns>
        public T ListRangeLast<T>(string redisKey)
            where T : class, new();
        /// <summary>
        /// 在列表尾部插入值。如果键不存在，先创建再插入值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        Task<long> ListRightPushAsync(string redisKey, string redisValue);
        Task<long> ListRightPushAsync(string redisKey, object redisValue);
        Task ListRightPushAsync<T>(string redisKey, List<T> redisValue);
        void ListRightPush<T>(string redisKey, List<T> redisValue);
        long ListRightPush(string redisKey, string redisValue);
        long ListRightPush(string redisKey, object redisValue);
        /// <summary>
        /// 在列表尾部插入数组集合。如果键不存在，先创建再插入值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        Task<long> ListRightPushAsync(string redisKey, IEnumerable<string> redisValue);
        Task<List<T>> ListRangeAsync<T>(string redisKey) where T : class;

        List<T> ListRange<T>(string redisKey) where T : class;

        List<string> ListRange(string redisKey);
        /// <summary>
        /// 在列表尾部插入数组集合。如果键不存在，先创建再插入值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        Task<long> ListRightPushAsync<T>(string redisKey, IEnumerable<T> redisValue);


        /// <summary>
        /// 修改LIST指定位置值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        Task ListSetAtAsync(string redisKey, long at, object redisValue);

        /// <summary>
        /// 修改LIST指定位置值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        void ListSetAt(string redisKey, long at, object redisValue);

        /// <summary>
        /// 获取LIST指定位置值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        Task<T> ListGetAtAsync<T>(string redisKey, long at) where T : class;

        /// <summary>
        /// 获取LIST指定位置值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
         T ListGetAt<T>(string redisKey, long at) where T : class;

        /// <summary>
        /// 获取LIST指定位置值 
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        public T GetListIndex<T>(string redisKey, long at) where T : class;
        /// <summary>
        /// 获取LIST指定位置值 
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
         string GetListIndex(string redisKey, long at);
        /// <summary>
        /// 获取LIST指定位置值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        string ListGetAt(string redisKey, long at);

        /// <summary>
        /// 移除并返回存储在该键列表的第一个元素  反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        Task<T> ListLeftPopAsync<T>(string redisKey) where T : class;

        /// <summary>
        /// 移除并返回存储在该键列表的第一个元素  反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redisKey"></param>
        /// <returns></returns>
         T  ListLeftPop<T>(string redisKey) where T : class;

        /// <summary>
        /// 移除并返回存储在该键列表的最后一个元素   反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        Task<T> ListRightPopAsync<T>(string redisKey) where T : class;


        // <summary>
        /// 移除并返回存储在该键列表的最后一个元素   反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redisKey"></param>
        /// <returns></returns>
          T ListRightPop<T>(string redisKey) where T : class;
        /// <summary>
        /// 移除并返回存储在该键列表的第一个元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        Task<string> ListLeftPopAsync(string redisKey);

        /// <summary>
        /// 移除并返回存储在该键列表的最后一个元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        Task<string> ListRightPopAsync(string redisKey);

        /// <summary>
        /// 移除并返回存储在该键列表的最后一个元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        string ListRightPop(string redisKey);


        /// <summary>
        /// 返回存储在该键列表的最后一个元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        string ListRight(string redisKey);
        /// <summary>
        /// 列表长度
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        Task<long> ListLengthAsync(string redisKey);
        /// <summary>
        /// 列表长度
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        long  ListLength(string redisKey);
        /// <summary>
        /// 返回在该列表上键所对应的元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        Task<IEnumerable<string>> ListRangeAsync(string redisKey, int db = -1);

        /// <summary>
        /// 根据索引获取指定位置数据
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns></returns>
        Task<IEnumerable<string>> ListRangeAsync(string redisKey, int start, int stop);

        /// <summary>
        /// 根据索引获取指定位置数据
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns></returns>
         IEnumerable<string>  ListRange(string redisKey, int start, int stop);


        /// <summary>
        /// 删除List中的元素 并返回删除的个数
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        Task<long> ListDelRangeAsync(string redisKey, string redisValue, long type = 0);

        /// <summary>
        /// 删除List中的元素 并返回删除的个数
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        long  ListDelRange(string redisKey, string redisValue, long type = 0);
        /// <summary>
        /// 清空List
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        Task ListClearAsync(string redisKey);
        void ListClear(string redisKey);


        /// <summary>
        /// 有序集合/定时任务延迟队列用的多
        /// </summary>
        /// <param name="redisKey">key</param>
        /// <param name="redisValue">元素</param>
        /// <param name="score">分数</param>
        Task SortedSetAddAsync(string redisKey, string redisValue, double score);
        /// <summary>
        /// 有序集合/定时任务延迟队列用的多
        /// </summary>
        /// <param name="redisKey">key</param>
        /// <param name="redisValue">元素</param>
        /// <param name="score">分数</param>
        void SortedSetAdd(string redisKey, string redisValue, double score);



        /// <summary>
        /// 有序集合数量
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        long SortedLength(string redisKey);


        /// <summary>
        /// 获取LIST指定值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        string? ListGetByIndex(string key, long index);

        /// <summary>
        /// 获取LIST指定对象
        /// </summary>
        /// <param name="key"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public T? ListGetByIndex<T>(string key, long index);


        /// <summary>
        /// 在LIST指定对象前添加
        /// </summary>
        /// <param name="key"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public void ListInsertBeforeIndex(string key, object data, long index);

        /// <summary>
        /// 在LIST指定对象后添加
        /// </summary>
        /// <param name="key"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public void ListInsertAfterIndex(string key, object data, long index);

        #region 获取Redis Key
        List<string> GetKeys(string name);
        #endregion
    }
}
